#ifndef __GKOS_MEMORY_H
#define __GKOS_MEMORY_H
#include "lib/global.h"
#include "memory/bitmap.h"

// *******************************************************************
// 定义分页用到的宏和变量
// 定义页目录和页表的属性
#define PAGE_DIR_BASE				0x1000
#define PAGE_SIZE                   0x1000	
#define PAGE_US_U					1<<2
#define PAGE_RW_W					1<<1
#define PAGE_P                      1<<0
#define PDE_INDEX_OFFSET            22
#define PTE_INDEX_OFFSET            12

// 页目录项虚拟地址
#define PDE(index)                  ((0xfffff000 | ((index) << 2)))
// 页表项虚拟地址
#define PTE(pdeindex, index)        (0xffc00000 | ((pdeindex) << 12) | ((index) << 2))
#define PDE_ADDR(addr)              (PDE((addr) >> PDE_INDEX_OFFSET))
#define PTE_ADDR(addr)              (PTE((addr) >> PDE_INDEX_OFFSET, BitVector((addr), 12, 21)))
#define REAL_ADDR(vaddr)            ((PTR32_R(PTE_ADDR((vaddr))) & (-1 << 12)) + ((vaddr) & 0xfff))

//内存单位
#define Unit_4K                     (1 << 12)
#define Unit_32K                    (1 << 15)
#define Unit_1M                     (1 << 20)

// 定义内存池地址
#define POOL_BASE                   0xc0030000
#define SYS_MEMORY_SIZE             (*((uint32_t*)0x700))

// 定义内存池类型
#define APPLY_FOR_KERNEL            0
#define APPLY_FOR_USER              1

struct pool_struct
{
    bitmap pool_bitmap;
    ptr_t memStart;
};
typedef struct pool_struct pool;
/*
* Function: InitMemory
* Return: void
* ----------------------------------------------------
* 初始化内存池的位图表示。共有物理内存，用户虚拟内存，内核虚拟内存三个内存池
*/
void InitMemory();
/*
* Function: ApplyMemory
* Return: 成功分配的内存起始地址(NULL代表分配失败)
* ----------------------------------------------------
* PoolType——0代表内核申请，1代表用户申请
*/
ptr_t ApplyMemory(uint32_t PoolType, uint32_t bytesSize);
/*
* Function: FreeMemory
* Return: void
* ----------------------------------------------------
* PoolType——0代表内核申请，1代表用户申请
*/
void FreeMemory(uint32_t PoolType, ptr_t BlockPos, uint32_t bytesSize);
/*
* Function: AddPageMap
* Return: void
* ----------------------------------------------------
* 该函数用于在页表中添加虚拟空间到物理空间的映射
*/
void AddPageMap(ptr_t allocVMemAddr, ptr_t allocRMemAddr, uint32_t pageCnt);

struct Memory_Ptr_Header
{
    uint32_t size;
    uint8_t  type;
};

/*
* Function: malloc_sys()
* Return: void
* ----------------------------------------------------
* 申请内存，内存块的前4个字节存储空间大小
* PoolType——0代表内核申请，1代表用户申请
*/
ptr_t malloc_sys(uint32_t PoolType, uint32_t bytesSize);
/*
* Function: free_sys()
* Return: void
* ----------------------------------------------------
* 释放内存, 内存开头4个字节存储空间大小
*/
void free_sys(ptr_t BlockPos);
#endif